home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994 February: Tool Chest / Dev.CD Feb 94.toast / New System Software Extensions / QuickDraw™ GX v1.0ß2 / Sample Code / Typography Samples / AdjustLayoutSample ƒ / AdjustLayoutSample.c next >
Encoding:
C/C++ Source or Header  |  1993-09-10  |  8.9 KB  |  344 lines  |  [TEXT/MPS ]

  1. /*
  2.     Kerning Adjustment Layout Sample Program
  3.     By Eric Mader,
  4.     After Mike Fairman, Oliver Steele et. al.
  5.     
  6. */
  7.  
  8. /* Copyright ©1989, 1990, 1991, 1992 Apple Computer, Inc.  All rights reserved. */
  9.  
  10.  
  11. #ifndef THINK_C
  12. #include <Quickdraw.h>
  13. #include <Fonts.h>
  14. #include <Windows.h>
  15. #include <Dialogs.h>
  16. #include <Events.h>
  17. #include <Memory.h>
  18. #include <Menus.h>
  19. #include <String.h>
  20. #include <Desk.h>
  21. #include <Script.h>
  22. #include <ToolUtils.h>
  23. #endif
  24.  
  25. #define thePort qd.thePort
  26. #define screenBits qd.screenBits
  27.  
  28. #include "graphics libraries.h"
  29. #include "qd library.h"
  30. #include "graphics debugging.h"
  31. #include "graphics errors.h"
  32. #include "graphics routines.h"
  33. #include "graphics toolbox.h"
  34.  
  35. #include "layout types.h"
  36. #include "layout routines.h"
  37. #include "layout library.h"
  38. #include "layout feature constants.h"
  39.  
  40.  
  41. /* This macro is useful for constructing fixed values */
  42. #define f(a,b) (((fixed) (a) << 16) + (b))
  43.  
  44. /* various menu and dialog things */
  45. enum {aboutDLOG = 128, appleMenuID = 128, fileMenuID, editMenuID}; /* resource ID's */
  46.  
  47. enum {okButton = 1, showsItem, authorItem};
  48.  
  49. enum {
  50.     /* Apple Menu */
  51.     aboutCommand = 1,
  52.     
  53.     /* File Menu */
  54.     quitCommand = 1,
  55.     
  56.     /* Edit Menu */
  57.     undoCommand = 1,
  58.     cutCommand,
  59.     copyCommand,
  60.     pasteCommand,
  61.     clearCommand};
  62.  
  63. WindowPtr myWindow, whichWindow;
  64. gxViewPort myPort;
  65. Rect qdWindowRect;
  66. Rect growRect = {40, 40, 32767, 32767};
  67. Rect bigRect = {-32768, -32768, 32767, 32767};
  68. gxRectangle windowRect;
  69.  
  70. MenuHandle appleMenu, fileMenu, editMenu;
  71. Boolean done = false;
  72.  
  73. gxColor colorWhite = xRGB (0xFFFF, 0xFFFF, 0xFFFF);    /* white */
  74. gxColor hsvInitial = xHSV (0, 0xFFFF, 0xFFFF); /* red */
  75.  
  76. static void ShowAboutBox ()
  77. {    GrafPtr savePort;
  78.     DialogPtr theDialog;
  79.     short itemType;
  80.     Handle itemHdl;
  81.     Rect itemRect;
  82.     short itemHit;
  83.  
  84.     GetPort(&savePort);
  85.     theDialog = GetNewDialog(aboutDLOG, nil, (WindowPtr) -1);
  86.     SetPort(theDialog);
  87.  
  88.     GetDItem(theDialog, authorItem, &itemType, &itemHdl, &itemRect);
  89.     SetIText(itemHdl, (StringPtr) "\pRice Dream");
  90.     GetDItem(theDialog, showsItem, &itemType, &itemHdl, &itemRect);
  91.     SetIText(itemHdl, (StringPtr) "\pKerning Adjustment");
  92.  
  93.     do {
  94.         ModalDialog(nil, &itemHit);
  95.     } while (itemHit != okButton);
  96.  
  97.     CloseDialog(theDialog);
  98.  
  99.     SetPort(savePort);
  100. }
  101.  
  102. static void SetupMenus ()
  103. {
  104.     InsertMenu (appleMenu = GetMenu (appleMenuID), 0);
  105.     AddResMenu (appleMenu, (ResType) 'DRVR');
  106.     InsertMenu (fileMenu = GetMenu (fileMenuID), 0);
  107.     InsertMenu (editMenu = GetMenu (editMenuID), 0);
  108.     DrawMenuBar ();
  109. }
  110.  
  111. static void DoMenuCommand (long mResult)
  112. {    short theItem = LoWord (mResult), theMenuID = HiWord (mResult);
  113.     GrafPtr savePort;
  114.     Str255 daName;
  115.     
  116.     switch (theMenuID)
  117.     {    case appleMenuID:
  118.             if (theItem == aboutCommand) ShowAboutBox ();
  119.             else
  120.             {    GetItem (appleMenu, theItem, daName);
  121.                 GetPort (&savePort);
  122.                 (void) OpenDeskAcc (daName);
  123.                 SetPort (savePort);
  124.             }
  125.         break;
  126.             
  127.         case fileMenuID:
  128.             if (theItem == quitCommand) done = true;
  129.         break;
  130.             
  131.         case editMenuID:
  132.         break;
  133.     }
  134.     
  135.     HiliteMenu (0);
  136. }
  137.  
  138. static short StrLength(char *s)
  139. {short len;
  140.  
  141.     for (len = 0; *s++ != 0; len++) ;
  142.     return len;
  143. }
  144.  
  145. #define withFactor {0, -ff(4)/30}
  146. #define crossFactor {0, fixed1/3}
  147. #define glyphA 36
  148. #define glyphE (glyphA + 'E' - 'A')
  149. #define glyphJ (glyphA + 'J' - 'A')
  150. #define glyphK (glyphA + 'K' - 'A')
  151. #define glyphN (glyphA + 'N' - 'A')
  152. #define glyphU (glyphA + 'U' - 'A')
  153. #define glyphV (glyphA + 'V' - 'A')
  154. #define glyphW (glyphA + 'W' - 'A')
  155. #define glyphY (glyphW + 2)
  156. #define nAdjustments 3
  157. #define nSubstitutions 4
  158.  
  159. void main()
  160. {    EventRecord theEvent;
  161.     gxShape layout, whiteOut;
  162.     gxRunControls controls;
  163.     gxLayoutOptions gxLayoutOptions;
  164.     StyleRunOverrides overrides;
  165.     gxStyle glyphStyles[3];
  166.     char *text1 = "Office";
  167.     char *text2 = "AWAY AND SOME ";
  168.     char *text3 = "JUNK.";
  169.     char *textRuns[3];
  170.     short level0 = 0, textLengths[3], totalLength;
  171.     gxKerningAdjustment adjustments[nAdjustments] = {{glyphA, glyphW, withFactor, crossFactor}, {glyphA, glyphY, withFactor, crossFactor}, {glyphW, glyphA, withFactor, crossFactor}};
  172.     gxGlyphSubstitution substitutions[nSubstitutions] = {{glyphJ, glyphW}, {glyphK, glyphE}, {glyphN, glyphV}, {glyphU, glyphA}};
  173.     gxPoint posn;
  174.     GDHandle max;
  175.     short mbh = GetMBarHeight ();
  176.     
  177.     MaxApplZone(); MoreMasters(); MoreMasters();
  178.     SetGraphicsLibraryErrors();
  179.     SetGraphicsLibraryNotices ();
  180. /*    GXSetValidation(gxInternalValidation | gxStructureValidation | gxNoMemoryManagerValidation);    /* uncomment this for less speed and more error-checking */
  181.  
  182.     InitGraf(&thePort);
  183.     InitFonts();
  184.     InitWindows();
  185.     InitMenus ();
  186.     InitCursor();
  187.  
  188.     SetupMenus ();
  189.     
  190.     /* find the deepest monitor, and make a window that just covers it */
  191.     max = GetMaxDevice (&bigRect);
  192.     qdWindowRect = (**max).gdRect;
  193.     
  194.     /* bring it down one mbh for the header, maybe another if on main screen */
  195.     if (qdWindowRect.top == 0 && qdWindowRect.left == 0) qdWindowRect.top += mbh;
  196.     qdWindowRect.top += mbh;
  197.         
  198.     InsetRect (&qdWindowRect, 4, 4);
  199.     ShortRectToFixed (&qdWindowRect, &windowRect);
  200.     
  201.     myWindow = NewWindow(nil, &qdWindowRect, (StringPtr) "\pKerning Adjustment Layout Sample",
  202.              true, documentProc, (WindowPtr) -1L, true, 0L);
  203.     
  204.     myPort = GXNewWindowViewPort (myWindow);
  205.     SetDefaultViewPort (myPort);
  206.     
  207.     /*
  208.          When we want to erase the whole window, we just GXDrawShape (whiteOut).
  209.      */
  210.     whiteOut = GXNewShape (gxFullType);
  211.     GXSetShapeColor (whiteOut, &colorWhite);
  212.  
  213.     /* gxInitialize the textRuns array */
  214.     textRuns[0] = text1;
  215.     textRuns[1] = text2;
  216.     textRuns[2] = text3;
  217.     
  218.     /* gxInitialize the textLengths array */
  219.     textLengths[0] = StrLength (text1);
  220.     textLengths[1] = StrLength (text2);
  221.     textLengths[2] = StrLength (text3);
  222.     
  223.     totalLength = textLengths[0] + textLengths[1] + textLengths[2];
  224.     
  225.     /* Make a default gxLayoutOptions, gxRunControls, and StyleRunOverrides */
  226.     InitializeLayoutOptions (&gxLayoutOptions);
  227.     InitializeRunControls (&controls);
  228.     InitializeStyleRunOverrides (&overrides);
  229.     
  230.     /*
  231.         Position the layout half way down the left edge of the window. Set 
  232.         the layout's width to the window's width and set the flushness to 1/2, this
  233.         will cause the layout to center in the window.
  234.     */
  235.     gxLayoutOptions.width = windowRect.right - windowRect.left;
  236.     gxLayoutOptions.flush = fract1/2;
  237.     posn.x = 0;
  238.     posn.y = (windowRect.bottom - windowRect.top) / 2;
  239.  
  240.     /* run 0 is 60 pt. Times Roman */
  241.     glyphStyles[0] = NewLayoutStyle((char *) "\pTimes Roman", ff(60), 0, &controls, nil, 0, nil);
  242.  
  243.     /*
  244.         Set the cross stream shift to 30 to raise the text 30 points,
  245.         and the with stream shift to -4 to move the text 4 points
  246.         closer together than normal kerning would move it.
  247.     */
  248.     controls.crossStreamShift = ff(30);
  249.  
  250.     overrides.kerningAdjustments = adjustments;
  251.     overrides.kerningAdjustmentsCount = nAdjustments;
  252.  
  253.     /* run 1 is 30 pt. Times Roman with kerning adjustments */
  254.     glyphStyles[1] = NewLayoutStyle((char *) "\pTimes Roman", ff(30), 0, &controls, nil, 0, &overrides);
  255.     
  256.     controls.crossStreamShift = 0;
  257.     overrides.kerningAdjustments = nil;
  258.     overrides.kerningAdjustmentsCount = 0;
  259.     overrides.glyphSubstitutions = substitutions;
  260.     overrides.glyphSubstitutionsCount = nSubstitutions;
  261.     
  262.     /* run 2 is 60 pt. Times Roman with glyph substitutions */
  263.     glyphStyles[2] = NewLayoutStyle((char *) "\pTimes Roman", ff(60), 0, &controls, nil, 0, &overrides);
  264.  
  265. /* Build and draw the layout. */
  266.     
  267.     layout = GXNewLayout(
  268.         3,
  269.         textLengths,
  270.         (void *) textRuns,
  271.         3,
  272.         textLengths,
  273.         glyphStyles,
  274.         1,
  275.         &totalLength,
  276.         &level0,
  277.         &gxLayoutOptions,
  278.         &posn);
  279.     GXDrawShape (layout);
  280.  
  281.     /* Now just spin in a simple event loop until it's time to go */
  282.     while (!done)
  283.     {
  284.         if (WaitNextEvent(everyEvent, &theEvent, 0, nil))
  285.         {
  286.             switch(theEvent.what)
  287.             {
  288.                 case mouseDown:
  289.                 switch (FindWindow(theEvent.where, &whichWindow))
  290.                 {    case inSysWindow:
  291.                         SystemClick(&theEvent, whichWindow);
  292.                         break;
  293.                     
  294.                     case inMenuBar:
  295.                         DoMenuCommand (MenuSelect (theEvent.where));
  296.                     break;
  297.                         
  298.                     case inDrag:
  299.                         DragWindow(whichWindow, theEvent.where, &screenBits.bounds);
  300.                     break;
  301.  
  302.                     case inGrow:
  303.                     {    register long newSize;
  304.  
  305.                         newSize = GrowWindow(whichWindow, theEvent.where, &growRect);
  306.                         SizeWindow(whichWindow, LoWord(newSize), HiWord(newSize), true);
  307.                     }
  308.                     break;
  309.                     
  310.                     case inGoAway:
  311.                         if (TrackGoAway(whichWindow, theEvent.where)) done = true;
  312.                     break;
  313.  
  314.                     case inContent:
  315.                         if (whichWindow != FrontWindow())
  316.                             SelectWindow(whichWindow);
  317.                     break;
  318.                 }
  319.                 break;
  320.  
  321.                 case keyDown:
  322.                 case autoKey:
  323.                     if (myWindow == FrontWindow () && theEvent.modifiers & cmdKey)
  324.                         DoMenuCommand (MenuKey (theEvent.message & charCodeMask));
  325.                 break;
  326.  
  327.                 case updateEvt:
  328.                     BeginUpdate((WindowPtr)theEvent.message);
  329.                     GXDrawShape (whiteOut);
  330.                     GXDrawShape (layout);
  331.                     EndUpdate((WindowPtr)theEvent.message);
  332.                 break;
  333.             }
  334.         }
  335.     }
  336.     /* dispose everything we've allocated. */
  337.     /* If we forget something, we'll get a warning when we call GXExitGraphics */
  338.     GXDisposeShape(layout);
  339.     GXDisposeStyle (glyphStyles[0]); GXDisposeStyle (glyphStyles[1]); GXDisposeStyle (glyphStyles[2]);
  340.     DisposeWindow(myWindow);
  341.     GXDisposeShape (whiteOut);
  342.     GXExitGraphics();
  343. }
  344.